package jmind.core.http;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import jmind.core.lang.Pair;
import jmind.core.util.DataUtil;
import jmind.core.util.GlobalConstants;

import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.httpclient.util.EncodingUtil;

public class HttpClient3 extends HttpClient {

    public String get(String url) {
        long start = System.currentTimeMillis();
        String res = null;
        org.apache.commons.httpclient.methods.GetMethod get = new org.apache.commons.httpclient.methods.GetMethod(url);
        get.setRequestHeader("Connection", "close");
        try {
            new org.apache.commons.httpclient.HttpClient().executeMethod(get);
            res = get.getResponseBodyAsString();
            statsCounter.mustGet(getURI(url)).recordSuccess(start);
            log(start, url, res);
        } catch (Exception e) {
            logger.error(url, e);
            statsCounter.mustGet(getURI(url)).recordException(start);
        } finally {
            get.releaseConnection();

        }
        return res;

    }

    /**
     * code 编码
     */
    public String get(String url, String code, int timeout) {
        org.apache.commons.httpclient.methods.GetMethod method = new org.apache.commons.httpclient.methods.GetMethod(
                url);
        return execute(url, code, timeout, method);

    }

    // http://m.blog.csdn.net/blog/java_lifei/14454977
    private String execute(String url, String code, int timeout, HttpMethod method) {
        if (DataUtil.isEmpty(code)) {
            code = GlobalConstants.ENCODE;
        }
        long start = System.currentTimeMillis();
        String res = null;
        org.apache.commons.httpclient.HttpClient httpClient = new org.apache.commons.httpclient.HttpClient();
        //    http://seanhe.iteye.com/blog/234759
        //        org.apache.commons.httpclient.HttpClient httpClient = new org.apache.commons.httpclient.HttpClient(
        //                new HttpClientParams(), new SimpleHttpConnectionManager(true));
        method.getParams().setContentCharset(code);
        method.getParams().setUriCharset(code);
        //  这个很重要，需要关闭连接
        method.setRequestHeader("Connection", "close");
        method.setRequestHeader("Accept-Charset", code);
        // 上传文件设置这个不行。
        //   method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=" + code);
        if (timeout > 0)
            method.getParams().setSoTimeout(timeout);
        // 默认就是这个不用设置
        //        getMethod.getParams().setParameter(org.apache.commons.httpclient.params.HttpMethodParams.SO_TIMEOUT,
        //                new org.apache.commons.httpclient.DefaultHttpMethodRetryHandler()); 
        try {
            int statusCode = httpClient.executeMethod(method);
            if (statusCode == HttpStatus.SC_OK) {
                res = new String(method.getResponseBody(), code);
            }
            statsCounter.mustGet(getURI(url)).recordSuccess(start);
            log(start, url, res);
        } catch (Exception e) {
            logger.error(url, e);
            statsCounter.mustGet(getURI(url)).recordException(start);
        } finally {
            method.releaseConnection();
            //   httpClient.getHttpConnectionManager().closeIdleConnections(0);

        }

        return res;
    }

    @Override
    public String post(String url, Map<String, ?> params, String code, int timeout) {
        //使用POST方法  
        PostMethod method = new PostMethod(url);
        if (!DataUtil.isEmpty(params)) {
            for (Entry<String, ?> pair : params.entrySet()) {
                method.setParameter(pair.getKey(), pair.getValue().toString());
            }
        }
        return this.execute(url, code, timeout, method);
    }

    @Override
    public String post(String url, List<Pair<String, String>> params, String code, int timeout) {
        PostMethod method = new PostMethod(url);
        if (!DataUtil.isEmpty(params)) {
            for (Pair<String, String> pair : params) {
                method.setParameter(pair.first, pair.second);
            }
        }
        return this.execute(url, code, timeout, method);

    }

    // http://blog.csdn.net/jdsjlzx/article/details/8825145
    @Override
    public String postFile(String url, Map<String, ?> params, String fileName, File file, String code) {
        try {
            PostMethod method = new PostMethod(url);
            int size = DataUtil.isEmpty(params) ? 1 : 1 + params.size();
            Part[] parts = new Part[size];
            parts[0] = new CustomFilePart(fileName, file, code);
            if (!DataUtil.isEmpty(params)) {
                int i = 1;
                for (Entry<String, ?> pair : params.entrySet()) {
                    parts[i++] = new StringPart(pair.getKey(), pair.getValue().toString(), code);
                }
            }

            //对于MIME类型的请求，httpclient建议全用MulitPartRequestEntity进行包装  
            MultipartRequestEntity mre = new MultipartRequestEntity(parts, method.getParams());
            method.setRequestEntity(mre);
            return this.execute(url, code, 0, method);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;

    }

    // 解决上传文件，文件名中文乱码问题 
    class CustomFilePart extends FilePart {

        public CustomFilePart(String name, File file, String code) throws FileNotFoundException {
            super(name, file, null, code);
        }

        protected void sendDispositionHeader(OutputStream out) throws IOException {
            super.sendDispositionHeader(out);
            String filename = getSource().getFileName();
            if (filename != null) {
                out.write(EncodingUtil.getAsciiBytes(FILE_NAME));
                out.write(QUOTE_BYTES);
                out.write(EncodingUtil.getBytes(filename, getCharSet()));
                out.write(QUOTE_BYTES);
            }
        }
    }

    @Override
    public String postBody(String url, String body) {
        PostMethod method = new PostMethod(url);
        if (!DataUtil.isEmpty(body)) {
            try {
                StringRequestEntity entity = new StringRequestEntity(body, null, GlobalConstants.ENCODE);
                method.setRequestEntity(entity);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return this.execute(url, GlobalConstants.ENCODE, 0, method);
    }

}
